<!doctype html>
<html lang="zh">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>DeepSeek 多模态图片识别</title>
    <style>
        body {
            font-family: system-ui, -apple-system, Segoe UI, Roboto, PingFang SC, Microsoft Yahei, sans-serif;
            margin: 20px;
        }

        .row {
            margin-bottom: 12px;
        }

        #output {
            white-space: pre-wrap;
            border: 1px solid #eee;
            padding: 8px;
            min-height: 100px;
        }

        textarea {
            width: 100%;
            height: 140px;
        }
    </style>
</head>

<body>
    <h2>DeepSeek 多模态图片识别（langchain-openai）</h2>
    <div class="row">
        <label>图片URL：</label>
        <input id="imageUrl" type="text" style="width: 420px" placeholder="https://..." />
    </div>
    <div class="row">
        <label>或 上传图片：</label>
        <input id="fileInput" type="file" accept="image/*" />
    </div>
    <div class="row">
        <label>Prompt：</label>
        <input id="prompt" type="text" style="width: 420px" value="请识别图片中的文字并总结要点。" />
    </div>
    <div class="row">
        <label>Model：</label>
        <input id="model" type="text" value="deepseek-vl" />
    </div>
    <div class="row">
        <button id="btnRecognize">识别</button>
    </div>

    <h3>Base64 工具</h3>
    <div class="row">
        <button id="btnB64File">将文件转为 Base64</button>
        <button id="btnB64Url">将 URL 转为 Base64</button>
        <button id="btnCopy">复制 Base64</button>
    </div>
    <div class="row">
        <textarea id="base64Out" placeholder="这里显示 Base64（data URL）"></textarea>
    </div>

    <h3>输出</h3>
    <div id="output"></div>

    <script>
        function blobToBase64(blob) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();
                reader.onload = () => resolve(String(reader.result));
                reader.onerror = reject;
                reader.readAsDataURL(blob);
            });
        }

        function fileToBase64(file) { return blobToBase64(file); }

        async function urlToBase64(url) {
            const res = await fetch(url);
            const blob = await res.blob();
            return await blobToBase64(blob);
        }

        document.getElementById('btnRecognize').addEventListener('click', async () => {
            const output = document.getElementById('output');
            output.textContent = '';
            const form = new FormData();
            form.append('prompt', document.getElementById('prompt').value);
            form.append('model', document.getElementById('model').value);
            const url = document.getElementById('imageUrl').value.trim();
            if (url) form.append('image_url', url);
            const fileEl = document.getElementById('fileInput');
            if (fileEl.files && fileEl.files[0]) {
                form.append('file', fileEl.files[0]);
            }
            const resp = await fetch('/recognize', { method: 'POST', body: form });
            const data = await resp.json();
            if (!resp.ok) {
                output.textContent = '请求失败: ' + (data?.error || resp.status);
                return;
            }
            output.textContent = data.text || '';
        });

        document.getElementById('btnB64File').addEventListener('click', async () => {
            const out = document.getElementById('base64Out');
            out.value = '';
            const fileEl = document.getElementById('fileInput');
            if (fileEl.files && fileEl.files[0]) {
                try { out.value = await fileToBase64(fileEl.files[0]); } catch (e) { out.value = '失败: ' + (e?.message || e); }
            } else {
                out.value = '请先选择文件';
            }
        });
        document.getElementById('btnB64Url').addEventListener('click', async () => {
            const out = document.getElementById('base64Out');
            out.value = '';
            const url = document.getElementById('imageUrl').value.trim();
            if (!url) { out.value = '请先输入URL'; return; }
            try { out.value = await urlToBase64(url); } catch (e) { out.value = '失败: ' + (e?.message || e); }
        });
        document.getElementById('btnCopy').addEventListener('click', async () => {
            const out = document.getElementById('base64Out');
            if (!out.value) return;
            try { await navigator.clipboard.writeText(out.value); } catch { }
        });
    </script>
</body>

</html>